package com.haust.category.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.haust.commons.exception.DaoException;
import com.haust.commons.pojo.HaustResult;
import com.haust.category.dto.ContentCategoryDto;
import com.haust.category.service.ContentCategoryService;
import com.haust.dao.RedisDao;
import com.haust.mapper.TbContentCategoryMapper;
import com.haust.pojo.TbContentCategory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ContentCategoryServiceImpl implements ContentCategoryService {
    @Autowired
    private TbContentCategoryMapper tbContentCategoryMapper;

    @Value("${Haust.incr.contentCategory}")
    private String contentCategoryKey;

    @Autowired
    private RedisDao redisDao;


    @Override
    public HaustResult selectContentCategoryByParentId(Long parentId) {
        QueryWrapper<TbContentCategory> tbContentCategoryQueryWrapper = new QueryWrapper<>();
        tbContentCategoryQueryWrapper.eq("parent_id", parentId)
                .eq("status", 1);
        List<TbContentCategory> list = tbContentCategoryMapper.selectList(tbContentCategoryQueryWrapper);

        ArrayList<ContentCategoryDto> dtoList = new ArrayList<>(list.size());

        for (TbContentCategory t : list) {
            ContentCategoryDto contentCategoryDto = new ContentCategoryDto();
            BeanUtils.copyProperties(t, contentCategoryDto);

            dtoList.add(contentCategoryDto);
        }

        return HaustResult.ok(dtoList);
    }

    /**
     * 新增 内容分类
     * ：
     * 1、完整性处理
     * 2、新增内容分类名称不能为空，同级别的内容分类，不能有同名的正常状态的节点
     * 3、添加到数据库中
     *
     * @param tbContentCategory
     * @return
     */
    @Override
    @Transactional(rollbackFor = {DaoException.class})
    public HaustResult insertContentCategory(TbContentCategory tbContentCategory) {


        //非空校验、
        if (tbContentCategory.getName() == null || tbContentCategory.getName().trim().length() == 0) {
            return HaustResult.error("内容分类名称不能为空!");
        }
        //同名校验
        List<TbContentCategory> list = queryTbContentCategoryByParentId(tbContentCategory.getParentId());
        for (TbContentCategory t : list) {
            if (t.getName().equals(tbContentCategory.getName()) && t.getStatus() == 1) {
                return HaustResult.error("该内容分类名称已存在，请换个名称");
            }
        }

        Long incr = null;
        try {
            incr = redisDao.incr(contentCategoryKey);
        } catch (RuntimeException e) {
            return HaustResult.error("服务忙，请稍后再试！");
        }

        Date date = new Date();
        tbContentCategory.setId(incr);
        tbContentCategory.setCreated(date);
        tbContentCategory.setUpdated(date);
        tbContentCategory.setIsParent(false); //不是父节点
        tbContentCategory.setSortOrder(1);//排序1
        tbContentCategory.setStatus(1);//状态正常

        try {
            //新增数据库
            tbContentCategoryMapper.insert(tbContentCategory);
            //更新父节点的  isParent=true
            TbContentCategory parentEntity = new TbContentCategory();
            parentEntity.setId(tbContentCategory.getParentId());
            parentEntity.setUpdated(date);
            parentEntity.setIsParent(true);
            tbContentCategoryMapper.updateById(parentEntity);
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new DaoException("服务忙，请稍后再试！");
        }

        return HaustResult.ok();
    }

    @Override
    @Transactional(rollbackFor = {DaoException.class})
    public HaustResult deleteContentCategoryById(Long id) {

        Date date = new Date();
        //级联删除
        try {
            deleteContentCategory(id, date);
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new DaoException("删除失败，稍后重试！");
        }

        //如果 当前节点的父节点没有有效的子节点，将当前节点设置为 isParent=false;
        TbContentCategory cur = tbContentCategoryMapper.selectById(id);
        if (getSiblings(cur.getParentId()) == 0) {
            //说明没有 正常状态的子节点、
            TbContentCategory parent = tbContentCategoryMapper.selectById(cur.getParentId());
            parent.setUpdated(date);
            parent.setIsParent(false);

            try {
                tbContentCategoryMapper.updateById(parent);
            } catch (RuntimeException e) {
                throw new DaoException("父节点设置失败");
            }
        }

        return HaustResult.ok();
    }


    /**
     * 根据id修改 ，内容分类的 name
     * ：
     * 1、修改的 name不能为null 或者 空字符串
     * 2、修改 时候 不能存在 同一 级别正常状态下相同 名字的 name
     *
     * @param id
     * @param name
     * @return
     */
    @Override
    @Transactional(rollbackFor = {DaoException.class})
    public HaustResult updateContentCategory(Long id, String name) {

        //非空 校验
        if (name == null || name.trim().length() == 0) {
            System.out.println("name == null || name.trim().length() == 0");
            return HaustResult.error("名字不能为空或空字符串");
        }
        TbContentCategory tbContentCategory = tbContentCategoryMapper.selectById(id);

        //同名校验
        List<TbContentCategory> list = queryTbContentCategoryByParentId(tbContentCategory.getParentId());
        for (TbContentCategory t : list) {
            System.out.println("list------------------"+list);
            if (!t.getId().equals(id)  && t.getName().equals(name) && t.getStatus() == 1) {
                return HaustResult.error("该内容分类名称已存在，请换个名称");
            }
        }


        Date updated = tbContentCategory.getUpdated();

        //以 上一次修改的时间 为准 进行修改
        QueryWrapper<TbContentCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id)
                .eq("updated", updated);

        TbContentCategory prepareUpdateData = new TbContentCategory();

        prepareUpdateData.setId(id);
        prepareUpdateData.setUpdated(new Date());
        prepareUpdateData.setName(name);

        try {
            tbContentCategoryMapper.update(prepareUpdateData, queryWrapper);
        } catch (RuntimeException e) {
            throw new DaoException("更新失败！");
        }
        return HaustResult.ok();
    }

    private int getSiblings(Long id) {
        int count = 0;
        QueryWrapper<TbContentCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        List<TbContentCategory> list = tbContentCategoryMapper.selectList(queryWrapper);
        for (TbContentCategory t : list) {
            if (t.getStatus() == 1) count++;
        }
        return count;
    }


    private void deleteContentCategory(Long id, Date date) {
        TbContentCategory cur = tbContentCategoryMapper.selectById(id);

        if (cur.getIsParent()) {
            //如果当前节点是 父节点
            //遍历子节点进行 批量状态改变
            QueryWrapper<TbContentCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id", cur.getId());
            List<TbContentCategory> list = tbContentCategoryMapper.selectList(queryWrapper);

            for (TbContentCategory t : list) {
                deleteContentCategory(t.getId(), date);
            }
        }
        //修改 当前节点的状体为 已经删除
        cur.setUpdated(date);
        cur.setStatus(2);
        tbContentCategoryMapper.updateById(cur);

    }

    private List<TbContentCategory> queryTbContentCategoryByParentId(Long parentId) {
        QueryWrapper<TbContentCategory> tbContentCategoryQueryWrapper = new QueryWrapper<>();
        tbContentCategoryQueryWrapper.eq("parent_id", parentId);
        return tbContentCategoryMapper.selectList(tbContentCategoryQueryWrapper);
    }
}
